<!--
 * Copyright © 2022 XXXXXXXXX
 * @Author: zhangxiang
 * @Date: 2022-07-19 09:42:10
 * @LastEditors: zhangxiang
 * @LastEditTime: 2023-09-21 14:21:02
 * @Description:
 *
-->

<template>
  <MyContainer class="app-service-index-container">
    <MyHeader class="header">
      <span class="name">应用名称</span>
      <el-input
        v-model="applicationName"
        style="width: 170px; margin-left: 10px; margin-right: 20px"
        size="medium"
        class="input"
        placeholder="请输入应用名称"
        clearable
        @clear="clearNameClick"
        @keyup.enter.native="queryClick"
      />
      <span class="name">分类</span>
      <el-select
        v-model="category"
        placeholder="请选择应用分类"
        size="medium"
        style="width: 170px; margin-left: 10px; margin-right: 20px"
      >
        <el-option
          v-for="item in categoryOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      <el-button
        size="medium"
        type="primary"
        @click="queryClick"
      >查询</el-button>
      <el-button size="medium" @click="resetClick">重置</el-button>
      <el-button
        size="medium"
        style="margin-left: auto"
        type="primary"
        icon="el-icon-upload2"
        @click="uploadClick"
      >上传应用</el-button>
    </MyHeader>
    <div class="view-type">
      <img
        class="icon"
        alt=""
        :src="viewType === 'grid' ? iconViewGrid : iconViewList"
      />
      <div class="wrapper">
        <div @click="changeViewType('grid')"></div>
        <div @click="changeViewType('list')"></div>
      </div>
    </div>
    <MyMain
      ref="mainCtn"
      :class="['main', viewType === 'grid' ? 'special' : '']"
    >
      <template v-if="viewType === 'grid'">
        <div
          v-if="list.length > 0"
          class="grid"
          :style="{ 'grid-template-columns': gridColumns.join(' ') }"
        >
          <div class="upload-item" @click="uploadClick">
            <i class="el-icon-circle-plus icon"></i>
            <span>上传应用</span>
          </div>
          <div
            v-for="(item, index) in list"
            :key="index"
            :class="['grid-item']"
          >
            <div class="top">
              <div class="name">{{ item.name }}</div>
              <img
                class="img edit"
                src="@/assets/imgs/app-service/icon_edit.png"
                alt=""
                @click="appEditClick(item)"
              />
              <el-popover
                :ref="`popover-delete-grid-${index}`"
                placement="top"
                width="300"
              >
                <p>是否确认删除该应用？</p>
                <div style="text-align: right; margin: 0">
                  <el-button
                    size="mini"
                    type="text"
                    @click="$refs[`popover-delete-grid-${index}`][0].doClose()"
                  >取消</el-button>
                  <el-button
                    type="primary"
                    size="mini"
                    @click="appDeleteClick(item, index)"
                  >确定</el-button>
                </div>
                <img
                  slot="reference"
                  class="img"
                  src="@/assets/imgs/app-service/icon_delete.png"
                  alt=""
                />
              </el-popover>
            </div>
            <div class="center">
              <img
                class="icon"
                alt=""
                :src="getAppCategoryImg(item.category)"
              />
              <div class="line"></div>
              <div class="center-right">
                <div class="item">
                  <div class="ititle" style="min-width: 60px">应用大小</div>
                  <div class="content">{{ item.size }}</div>
                </div>
                <div class="item right">
                  <div class="ititle" style="min-width: 36px">分类</div>
                  <div class="content">
                    {{ getAppCategoryChn(item.category) }}
                  </div>
                </div>
                <div class="item">
                  <div class="ititle" style="min-width: 60px">应用版本</div>
                  <div class="content">{{ item.version }}</div>
                </div>
                <div class="item right">
                  <div class="ititle" style="min-width: 36px">提供者</div>
                  <div class="content">{{ item.provider }}</div>
                </div>
                <div class="item last">
                  <div class="ititle" style="min-width: 60px">部署资源池</div>
                  <div v-if="item.deployResourceInfo" class="content">
                    {{ getCloudScopeText(item.deployResourceInfo.cloudScope) }}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div v-else class="grid-none">暂无数据</div>
      </template>
      <template v-if="viewType === 'list'">
        <el-table
          v-loading="loading"
          :data="list"
          stripe
          header-cell-class-name="listHeaderCell"
          :header-cell-style="{ color: '#696969' }"
        >
          <el-table-column prop="name" label="应用名称" />
          <el-table-column prop="size" label="大小" />
          <el-table-column prop="category" label="分类">
            <template slot-scope="scope">
              {{ getAppCategoryChn(scope.row.category) }}
            </template>
          </el-table-column>
          <el-table-column prop="version" label="应用版本" />
          <el-table-column prop="deployResourceInfo" label="部署资源池">
            <template slot-scope="scope">
              <span v-if="scope.row.deployResourceInfo">{{
                getCloudScopeText(scope.row.deployResourceInfo.cloudScope)
              }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="provider" label="提供者" />
          <el-table-column prop="updateTime" label="更新时间" />
          <el-table-column label="操作" width="140">
            <template slot-scope="scope">
              <el-button
                type="primary"
                size="mini"
                style="height: 22px; line-height: 22px; padding: 0 10px"
                @click="appEditClick(scope.row)"
              >编辑</el-button>
              <el-popover
                :ref="`popover-delete-${scope.$index}`"
                placement="top"
                width="300"
                style="margin-left: 10px"
              >
                <p>是否确认删除该应用？</p>
                <div style="text-align: right; margin: 0">
                  <el-button
                    size="mini"
                    type="text"
                    @click="
                      scope._self.$refs[
                        `popover-delete-${scope.$index}`
                      ].doClose()
                    "
                  >取消</el-button>
                  <el-button
                    type="primary"
                    size="mini"
                    @click="appDeleteClick(scope.row, scope.$index)"
                  >确定</el-button>
                </div>
                <el-button
                  slot="reference"
                  type="danger"
                  style="height: 22px; line-height: 22px; padding: 0 10px"
                  size="mini"
                >删除</el-button>
              </el-popover>
            </template>
          </el-table-column>
        </el-table>
      </template>
      <el-row type="flex" justify="end" style="margin-top: 30px">
        <el-pagination
          background
          layout="total, sizes, prev, pager, next"
          :page-sizes="viewType === 'list' ? sizesList : sizesGrid"
          :page-size="pageSize"
          :current-page.sync="pageNum"
          :total="totalSize"
          @current-change="changePage"
          @size-change="sizeChange"
        />
      </el-row>
    </MyMain>

    <UploadAppDialog
      v-if="showUploadDialog"
      :show.sync="showUploadDialog"
      :is-edit="isEditDialog"
      :app-info="currentEditAppInfo"
      @edit-success="editSuccessCallback"
      @upload-success="uploadSuccessCallback"
    />
  </MyContainer>
</template>

<script>
import pageResize from '@/views/mixin/pageResize.js'
import MyContainer from '@/components/Layout/MyContainer.vue'
import MyHeader from '@/components/Layout/MyHeader.vue'
import MyMain from '@/components/Layout/MyMain.vue'
import UploadAppDialog from '../components/UploadAppDialog.vue'
import { getAppList, deleteApp } from '@/api/cnap/app-service'
import { APP_CATEGORYS } from '@/utils/cnap/constant'

export default {
  name: 'AppServiceIndex',
  components: {
    MyContainer,
    MyHeader,
    MyMain,
    UploadAppDialog
  },
  mixins: [pageResize],
  data() {
    return {
      gridColumns: ['1fr', '1fr', '1fr', '1fr'],
      categoryOptions: APP_CATEGORYS, // 类别选项
      sizesList: [10, 15, 20], // size数组
      sizesGrid: [11, 15, 19], // size数组
      applicationName: '', // 应用名
      category: '', // 类别
      loading: false, // 加载中
      pageSize: 10, // size
      pageNum: 1, // 页码
      totalSize: 0, // 总数
      list: [], // 数据
      viewType: 'grid', // 展示类别
      iconViewGrid: require('@/assets/imgs/app-service/icon_view_grid.png'), // icon
      iconViewList: require('@/assets/imgs/app-service/icon_view_list.png'), // icon
      showUploadDialog: false, // 显示上传弹窗
      isEditDialog: false, // 是否是编辑
      currentEditAppInfo: {} // 当前编辑信息
    }
  },
  computed: {},
  mounted() {
    this.computeGridColumns()
    this.pageSize =
      this.viewType === 'list' ? this.sizesList[0] : this.sizesGrid[0] // 初始化pageSize
    this.initPageData() // 初始化数据
  },
  created() {},
  methods: {
    /**
     * @description: 重新布局
     * @return {*}
     */
    resize() {
      this.computeGridColumns()
    },
    /**
     * @description: 计算grid列数
     * @return {*}
     */
    computeGridColumns() {
      const ctnWidth = this.$refs.mainCtn.$el.clientWidth
      if (ctnWidth > 1300) {
        this.gridColumns = ['1fr', '1fr', '1fr', '1fr']
      } else if (ctnWidth > 960) {
        this.gridColumns = ['1fr', '1fr', '1fr']
      } else if (ctnWidth > 600) {
        this.gridColumns = ['1fr', '1fr']
      } else {
        this.gridColumns = ['1fr']
      }
      this.sizesGrid = [
        this.gridColumns.length * 3 - 1,
        this.gridColumns.length * 4 - 1,
        this.gridColumns.length * 5 - 1
      ]
      this.pageSize = this.sizesGrid[0]
    },
    /**
     * @description: 获取资源池文字
     * @param {*} cloudScope
     * @return {*}
     */
    getCloudScopeText(cloudScope) {
      return cloudScope === 'public'
        ? '公有云'
        : cloudScope === 'private'
          ? '私有云'
          : cloudScope
    },
    /**
     * @description: 上传
     * @return {*}
     */
    uploadClick() {
      this.currentEditAppInfo = {}
      this.isEditDialog = false
      this.showUploadDialog = true
    },
    /**
     * @description: 上传成功回调
     * @return {*}
     */
    uploadSuccessCallback() {
      this.$message.success({
        message: '上传应用成功',
        duration: 2000
      })
      this.applicationName = ''
      this.category = ''
      this.pageNum = 1
      this.getAppList()
    },
    /**
     * @description: 编辑成功回调
     * @return {*}
     */
    editSuccessCallback() {
      this.$message.success({
        message: '编辑成功',
        duration: 2000
      })
      this.getAppList()
    },
    /**
     * @description: 编辑
     * @param {*} item
     * @return {*}
     */
    appEditClick(item) {
      if (item.status !== 1) {
        // 状态
        // 1：正常状态（已上传应用包）
        // 2：已拆解，未完全部署
        // 3：已部署
        this.$message.warning({
          message: '已拆解的应用不支持编辑',
          duration: 2000
        })
        return
      }
      this.currentEditAppInfo = item
      this.isEditDialog = true
      this.showUploadDialog = true
    },
    /**
     * @description: 删除应用
     * @param {*} item
     * @param {*} index
     * @return {*}
     */
    appDeleteClick(item, index) {
      // 删除接口
      deleteApp(item.id).then((res) => {
        if (this.viewType === 'grid') {
          this.$refs[`popover-delete-grid-${index}`][0].doClose()
        } else {
          this.$refs[`popover-delete-${index}`].doClose()
        }
        this.$message.success('删除成功')
        if (this.list.length === 1) {
          // 当前页只有一条数据时 删除完则请求上一页数据
          this.pageNum = Math.max(this.pageNum - 1, 1)
        }
        this.getAppList()
      })
    },
    /**
     * @description: 获取应用类别图标
     * @param {*} category
     * @return {*}
     */
    getAppCategoryImg(category) {
      if (category === 'BIGDATA') {
        return require('@/assets/imgs/app-service/img_bigdata.png')
      }
      return require('@/assets/imgs/app-service/img_ai.png')
    },
    /**
     * @description: 获取应用类别中文
     * @param {*} category
     * @return {*}
     */
    getAppCategoryChn(category) {
      const option = this.categoryOptions.find((item) => {
        return item.value === category
      })
      return option ? option.label : ''
    },
    /**
     * @description: 切换展示方式
     * @param {*} viewType
     * @return {*}
     */
    changeViewType(viewType) {
      if (viewType === this.viewType) {
        return
      }
      this.viewType = viewType
      this.pageSize =
        this.viewType === 'list' ? this.sizesList[0] : this.sizesGrid[0]
      this.pageNum = 1
      this.getAppList()
    },
    /**
     * @description: size变化
     * @param {*} size
     * @return {*}
     */
    sizeChange(size) {
      this.pageSize = size
      this.pageNum = 1
      this.getAppList()
    },
    /**
     * @description: 切换页码
     * @param {*} pageNum
     * @return {*}
     */
    changePage(pageNum) {
      this.pageNum = pageNum
      this.getAppList()
    },
    /**
     * @description: 清除名称
     * @return {*}
     */
    clearNameClick() {
      this.applicationName = ''
      this.pageNum = 1
      this.getAppList()
    },
    /**
     * @description: 重置
     * @return {*}
     */
    resetClick() {
      this.applicationName = ''
      this.category = ''
      this.pageNum = 1
      this.getAppList()
    },
    /**
     * @description: 查询
     * @return {*}
     */
    queryClick() {
      this.pageNum = 1
      this.getAppList()
    },
    /**
     * @description: 获取应用列表
     * @return {*}
     */
    getAppList() {
      // 请求应用数据
      getAppList({
        applicationName: this.applicationName,
        category: this.category,
        pageNum: this.pageNum,
        pageSize: this.pageSize
      })
        .then((res) => {
          if (res.data) {
            this.totalSize = res.data.totalSize
            this.list = Array.isArray(res.data.data) ? res.data.data : []
          } else {
            this.totalSize = 0
            this.list = []
          }
        })
        .finally(() => {
          this.loading = false
        })
    },
    /**
     * @description: 初始化数据
     * @return {*}
     */
    initPageData() {
      this.loading = true
      this.pageNum = 1
      this.getAppList()
    }
  }
}
</script>

<style lang="less" scoped>
@import "@/assets/css/common.less";
.app-service-index-container {
  .header {
    padding: 0px 25px;

    .name {
      .textStyle(14px , 400, #4a4a4a);
      line-height: 20px;
    }
  }
  .view-type {
    margin-left: auto;
    width: 60px;
    height: 33px;
    position: relative;

    .icon {
      width: 100%;
      height: 100%;
    }
    .wrapper {
      z-index: 1;
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      display: flex;
      align-items: center;
      justify-content: center;

      div {
        flex: 1;
        height: 100%;
        cursor: pointer;
      }
    }
  }
  .main {
    margin-top: 20px;
    padding: 0 0 20px 0;

    &.special {
      background: transparent;
      box-shadow: none;
      border-radius: 0;
    }

    .grid-none {
      text-align: center;
      margin: 64px 0;
      .textStyle(14px, 400, #696969);
    }

    .grid {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr 1fr;
      grid-template-rows: auto;
      grid-column-gap: 20px;
      grid-row-gap: 20px;

      .upload-item {
        cursor: pointer;
        box-sizing: border-box;
        height: 154px;
        background: #ffffff;
        border-radius: 4px;
        border: 1px dashed #979797;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;

        .icon {
          color: #0091ff;
          font-size: 20px;
        }

        span {
          .textStyle(14px, 400, #696969);
          line-height: 20px;
          padding-top: 3px;
        }
      }

      .grid-item {
        // min-width: 330px;
        box-sizing: border-box;
        height: 154px;
        background: #ffffff;
        box-shadow: 0px 0px 5px 0px rgba(217, 213, 234, 0.5);
        border-radius: 4px;

        .top {
          height: 42px;
          background: #0091ff;
          border-radius: 4px 4px 0px 0px;
          display: flex;
          align-items: center;
          padding: 0 20px;

          .name {
            .textStyle(16px, 600, #FFFFFF);
            line-height: 20px;
          }

          .img {
            width: 13px;
            cursor: pointer;

            &.edit {
              margin-left: auto;
              margin-right: 10px;
            }
          }

          /deep/ .el-popover__reference-wrapper {
            display: flex;
            align-items: center;
          }
        }

        .center {
          display: flex;
          align-items: center;
          justify-content: space-between;
          padding: 15px 20px 0;

          .icon {
            width: 75px;
            height: 75px;
          }

          .line {
            margin: 0 10px;
            width: 1px;
            height: 72px;
            background: #f2f2f2;
          }

          .center-right {
            min-width: 150px;
            .item {
              width: 57%;
              display: inline-flex;
              align-items: center;
              margin-bottom: 9px;
              height: 20px;
              &.right {
                width: 43%;
              }
              &.last {
                margin-bottom: 0;
              }
              .ititle {
                text-align: right;
                margin-right: 10px;
                .textStyle(12px , 400, #C3C3C3);
              }
              .content {
                .textStyle(14px , 500, #4a4a4a);
              }
            }
          }
        }
      }
    }

    .el-table::before {
      background-color: #f2f2f2;
    }
    /deep/ .listHeaderCell {
      height: 60px;
      border: none;
      box-sizing: border-box;
      &:first-child {
        padding-left: 25px;
      }
    }

    /deep/ .el-table__body {
      .el-table__row td {
        height: 40px;
        padding: 0;
        border-bottom: none;
        &:first-child {
          padding-left: 25px;
        }
      }
      .el-table__row {
        background: #f8f8f8;
      }
      .el-table__row--striped {
        background: #fff;
        .el-table__cell {
          background: transparent;
        }
      }
    }
    /deep/ .el-table tbody tr:hover > .el-table__cell {
      background: #eaeaea;
    }
  }
}
</style>
